package booyah.web;

import booyah.application.Event;
import booyah.application.Position;
import booyah.application.User;
import booyah.service.EventService;
import booyah.service.UserService;
import booyah.validation.PositionValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

import javax.servlet.http.HttpSession;
import java.sql.Timestamp;

@Controller
public class PositionController {

    private final EventService eventService;
    private final UserService userService;

    @Autowired
    public PositionController(EventService eventService, UserService userService) {
        this.eventService = eventService;
        this.userService = userService;
    }

    @ModelAttribute
    public Position newRequest(@RequestParam(required = true) Long eventId, @RequestParam(required = false) Long id, Model model) {
        Position position = (id != null) ? eventService.findPositionByPositionId(id) : new Position();
        if (eventId != -1) {
            position.setEventId(eventId);
        }
        return position;
    }

    @InitBinder
    public void setAllowedFields(WebDataBinder dataBinder) {
        TimestampEditor timestampEditor = new TimestampEditor();
        dataBinder.registerCustomEditor(Timestamp.class, timestampEditor);
    }

    @RequestMapping(method = RequestMethod.GET)
    public void details() {
    }

    @RequestMapping(method = RequestMethod.GET)
    public void show(HttpSession session) {
    }

    @RequestMapping(method = RequestMethod.POST)
    public String show(@ModelAttribute Event event) {
        return "redirect:/controller/home";
    }

    @RequestMapping(method = RequestMethod.GET)
    public String volunteer(@ModelAttribute Position position, BindingResult result, HttpSession session) {
        User user = (User) session.getAttribute("user");
        position.addVolunteer(user);
        eventService.updatePosition(position);  // TODO remove this
        return "redirect:/controller/position/confirm?eventId=" + position.getEventId() + "&id=" + position.getId() + "&volunteerId=" + user.getId();
    }

    @RequestMapping(method = RequestMethod.GET, params = "volunteerId")
    public String unvolunteer(@RequestParam(required = true) Long eventId, @RequestParam(required = false) Long id, @RequestParam(required = false) Long volunteerId, @ModelAttribute Position position, BindingResult result, HttpSession session) {
        User user = userService.findUserById(volunteerId);
        position.removeVolunteer(user);
        eventService.updatePosition(position);
        return "redirect:/controller/position/form?eventId=" + position.getEventId() + "&id=" + position.getId();
    }

    @RequestMapping(method = RequestMethod.GET, params = "volunteerId")
    public void confirm(@RequestParam(required = true) Long eventId, @RequestParam(required = false) Long id, @RequestParam(required = false) Long volunteerId, @ModelAttribute Position position, BindingResult result, HttpSession session) {
    }

    @RequestMapping(method = RequestMethod.GET)
    public String delete(@ModelAttribute Position position, BindingResult result, HttpSession session) {
        Event event = eventService.findEventByEventId(position.getEventId());
        if (position.getVolunteers().size() != 0) {
            // TODO assign errors here
        } else {
            eventService.removePositionFromEvent(event, position);
        }

        return "redirect:/controller/event/form?id=" + event.getId();
    }


    @RequestMapping(method = RequestMethod.GET)
    public void form(Model model, HttpSession session) {

    }

    @RequestMapping(method = RequestMethod.POST)
    public String form(@ModelAttribute Position position, BindingResult result, SessionStatus status, HttpSession session) {
        PositionValidator.validate(position, result);
        if (result.hasErrors()) {
            return null; // Default view
        } else {
            if (!position.isNew()) {
                eventService.updatePosition(position);
            } else {
                Event event = eventService.findEventByEventId(position.getEventId());
                event.addPosition(position);
                eventService.updateEvent(event);
            }
            status.setComplete();
            return "redirect:/controller/event/form?id=" + position.getEventId();
        }
    }


}
